package com.gzz.common.tools;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.google.common.io.Files;
import lombok.extern.slf4j.Slf4j;

/**
 * @功能描述 【上传文件】工具
 * @author 高振中
 * @date 2021-03-08 20:20:20
 */
@Slf4j
@Component
public class FileTools {

	@Value(value = "${spring.rootpath}")
	private String rootPath;
	@Value(value = "${spring.rooturl}")
	private String rootUrl;

	/**
	 * @功能描述 保存文件(MultipartFile)
	 */
	public FileVo saveFile(MultipartFile file, String target) {
		String fileName = SysTools.uuid();// 生成主文件名
		String oriName = file.getOriginalFilename();// 原始文件名
		String extName = oriName.substring(oriName.lastIndexOf("."));// 扩展名
		String fullPath = rootPath + target + fileName + extName;// 完成路径
		createDir(fullPath);// 如果目录,不存在创建这个目录
		try {

			file.transferTo(new File(fullPath));// 保存文件
		} catch (IOException e) {
			log.error(fullPath);
			log.error("保文件时出现IOException异常!!", e);
		}
		return FileVo.builder().fileUrl(rootUrl + target + fileName + extName).filePath(target + fileName + extName).fileName(oriName).fileSize(getSize(file.getSize())).build();

	}

	/**
	 * @功能描述 保存文件(File)
	 */
	public FileVo saveFile(File file, String target) {
		String uuid = SysTools.uuid();// 生成主文件名
		String oriName = file.getName();// 原始文件名
		String extName = oriName.substring(oriName.lastIndexOf("."));// 扩展名
		String fullPath = rootPath + target + uuid + extName;// 完成路径
		createDir(fullPath);// 如果目录,不存在创建这个目录
		try {
			Files.copy(file, new File(fullPath));// 保存文件
		} catch (IOException e) {
			log.error("保文件时出现IOException异常!!", e);
		}
		return FileVo.builder().fileUrl(rootUrl + target + uuid + extName).filePath(target + uuid + extName).fileName(oriName).fileSize(getSize(file.length())).build();
	}

	/**
	 * 从已知的文件路径保存获取文件并保存
	 */
	public FileVo saveFile(String srcUrl, String targetPath) {
		return saveFile(getFileBytes(srcUrl), targetPath);
	}

	/**
	 * 从输入流中获取数据
	 */
	public FileVo saveFile(byte[] bytes, String target) {
		String uuid = SysTools.uuid();// 生成主文件名
		String extName = extName(bytes);
		String fullPath = rootPath + target + uuid + extName;// 完成路径
		createDir(fullPath);// 如果目录,不存在创建这个目录
		try {
			Files.write(bytes, new File(fullPath));// 保存文件
		} catch (IOException e) {
			log.error("保文件时出现IOException异常!!", e);
		}
		return FileVo.builder().fileUrl(rootUrl + target + uuid + extName).filePath(target + uuid + extName).fileName(uuid).fileSize(getSize(bytes.length)).build();
	}

	/**
	 * @功能描述 删除文件
	 */
	public boolean deleteFile(String path) {
		File file = new File(rootPath + path);
		return file.delete();
	}

	/**
	 * @方法说明 从url读取文件流
	 */
	private static byte[] getFileBytes(String imgUrl) {
		ByteArrayOutputStream swapStream = null;
		try {
			URL imgurl = new URL(imgUrl);
			URLConnection connection = imgurl.openConnection();
			InputStream inStream = connection.getInputStream();
			swapStream = new ByteArrayOutputStream();
			byte[] buff = new byte[1024 << 3];
			int rc = 0;
			while ((rc = inStream.read(buff, 0, 100)) > 0) {
				swapStream.write(buff, 0, rc);
			}
		} catch (IOException e) {
			log.error("从url读取文件流时发生IOException异常", e);
		}
		return swapStream.toByteArray();
	}

	/**
	 * @方法说明 取扩展名
	 */
	private static String extName(byte[] data) {
		try {
			if (data[1] == 'P' && data[2] == 'N' && data[3] == 'G') {
				return ".png";
			}
			if (data[0] == 'G' && data[1] == 'I' && data[2] == 'F') {
				return ".gif";
			}
			if (data[6] == 'J' && data[7] == 'F' && data[8] == 'I' && data[9] == 'F') {
				return ".jpg";
			}
			return ".jpg";
		} catch (Exception e) {
			log.info("取扩展名异常！", e);
		}
		return ".jpg";
	}

	/**
	 * @功能描述 计算文件大小
	 */
	private static String getSize(long size) {
		if (size >= 1024 * 1024) {
			return size / (1024 * 1024) + "M";
		}
		return size / 1024 + "K";
	}

	/**
	 * @功能描述 如果目录不存在创建这个目录
	 */
	private static void createDir(String path) {
		File file = new File(path);
		File parent = file.getParentFile();
		if (parent != null && !parent.exists()) {
			parent.mkdirs();
			parent.setWritable(true);
			parent.setReadable(true);
			parent.setExecutable(true);
		}
	}
}
